#include "../Hdr//VideoSystem.h"

#include <SDL/SDL_opengl.h>
#include "../Hdr/Globals.h"
#include "../Hdr/Input.h"

Eternal::Video::VideoSystem::VideoSystem(Core::InputManager *inputDev)
{
	InputSys = inputDev;
	renderMode = MODE_3D;
}

Eternal::Video::VideoSystem::~VideoSystem()
{
	
}

/* Initialize the video system ready for rendering */ 
void Eternal::Video::VideoSystem::Initialize(const unsigned int vertCacheSize, 
											 const unsigned int colCacheSize,
											 const unsigned int texCacheSize) const
{
	/* Initialize SDL */
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
	
	/* Setup vidoe attributes */
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
	
	/* Initialize Video */
	SDL_WM_SetCaption("navi-tech 1", NULL);
	if(SDL_SetVideoMode(640, 480, 32, SDL_OPENGL) == NULL)	{
		printf("Failed to initialize SDL\n");
	}
	
	/* Initialize OpenGL */
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-1, 1, -1, 1, 1, 10000);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	/* Allocate vertex data caching */
	VertCache = (float*)malloc(vertCacheSize * sizeof(float));
	ColorCache = (float*)malloc(colCacheSize * sizeof(float));
	TexCache = (float*)malloc(texCacheSize * sizeof(float));
	
	glEnable(GL_DEPTH);
//	glEnable(GL_DEPTH_TEST);
//	glEnable(GL_CULL_FACE);
	//glCullFace(GL_BACK);
	
	InputSys->Initialize();
}

/* Begins the video scene */
void Eternal::Video::VideoSystem::BeginScene()
{
	InputSys->BeginFrame();
	/* Poll for events */
	SDL_PollEvent(&event);
	if ( event.type == SDL_QUIT || InputSys->IsKeyPress(KEY_ESC) )	{
		SDL_Quit();
		return;
	}
	if ( renderMode == MODE_3D )	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	}
	else	{
		glClear(GL_COLOR_BUFFER_BIT);
	}
	i_Ticks = SDL_GetTicks();
}

/* Ends the video scene */
void Eternal::Video::VideoSystem::EndScene() const
{
	/* Regulate the frame rate */
	if ( (SDL_GetTicks() - i_Ticks) / 1000 > 1000 / 60 )
	{
		/* Halt the process for whatever given time */
		SDL_Delay((SDL_GetTicks() - i_Ticks) / 1000 - (1000 / 160));
	}
	SDL_GL_SwapBuffers();
}

/* Changes to 2D render mode */
void Eternal::Video::VideoSystem::RenderMode2D()
{
	if ( renderMode == MODE_2D )	{
		return;
	}
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, 640, 480, 0, -1, 1);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glDisable(GL_DEPTH_TEST);
	renderMode = MODE_2D;
}

/* Changes to 3D render mode */
void Eternal::Video::VideoSystem::RenderMode3D()
{
	if ( renderMode == MODE_3D )	{
		return;
	}
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-1, 1, -1, 1, 1, 10000);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glEnable(GL_DEPTH_TEST);
	renderMode = MODE_3D;
}

void Eternal::Video::VideoSystem::VideoSystem::RenderVerts(float *vertAddr, unsigned int size) const
{
	glVertexPointer(3, GL_FLOAT, 0, vertAddr);
	glDrawArrays(GL_QUADS, 0, size);
}